/*
 * reputacja.h
 *
 * Copyright (C) 2008, 2009
 *
 * Lukasz Bieniasz-Krzywiec
 * Dariusz Leniowski
 */

#ifndef REPUTACJA_H_
#define REPUTACJA_H_

#include "../config.h"

template <class O> // O czyli typ (klasa) osobnika
class reputacja {
public:
  reputacja() {}
  virtual ~reputacja() {}

  const O *w;

  /*
   * Konstruktor
   * Argumenty
   * - _w -- osobnik, ktorego reputacje bedziemy liczyc
   * Potrzebujemy osobnika, gdyz mozemy potrzebowac pobrac z niego dane (np. ostatnia wyplate, etc.)
   */
  reputacja(const O *_w) : w(_w) {}

  /*
   * Przelicz reputacje w danej turze
   * Zalozenia:
   * - w jest poprawnym wskaznikiem do osobnika
   * Wynik:
   * - funkcja wartosc zwroci przeliczana reputacje w tej turze
   */
  virtual void przelicz() = 0;

  /*
   * Zwraca reputacje
   * Zalozenia:
   * - wczesniej zostala wywolana funkcja przelicz
   */
  virtual real wartosc() = 0;
};

template <class O>
class reputacja_brak : public reputacja<O> {
public:
  reputacja_brak();
  ~reputacja_brak();

  reputacja_brak(const O*);

  void przelicz();
  real wartosc();
};

/*
 * Modul, ktory nie liczy niczego
 */

template <class O>
reputacja_brak<O>::reputacja_brak() {}

template <class O>
reputacja_brak<O>::~reputacja_brak() {}

template <class O>
reputacja_brak<O>::reputacja_brak(const O *o) : reputacja<O>(o) {};

template <class O>
void reputacja_brak<O>::przelicz() {}

template <class O>
real reputacja_brak<O>::wartosc() { return 0; }

/*
 * Modul, ktory liczy srednia kooperacje
 * Gdy nie ma jeszcze zadnych danych, zwraca 1/2
 * W metodach nie ma dodatkowych zalozen
 */

template <class O>
class reputacja_podstawowa : public reputacja<O> {
public:
  int   ile;              // ile probek mamy
  real  kooperacja_suma;  // suma probek

  reputacja_podstawowa();
  ~reputacja_podstawowa();

  reputacja_podstawowa(const O*);

  void przelicz();
  real wartosc();
};

template <class O>
reputacja_podstawowa<O>::reputacja_podstawowa() {}

template <class O>
reputacja_podstawowa<O>::~reputacja_podstawowa() {}

template <class O>
reputacja_podstawowa<O>::reputacja_podstawowa(const O* o) : reputacja<O>(o) {
  kooperacja_suma = 0;
  ile = 0;
}

template <class O>
void reputacja_podstawowa<O>::przelicz() {
  ile ++;
  kooperacja_suma += reputacja<O>::w->strategia;
}

template <class O>
real reputacja_podstawowa<O>::wartosc() {
  return ile?(kooperacja_suma/ile):0.5;
}

#endif /* REPUTACJA_H_ */

